#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@Project ：Employment_class
@File    ：04_fixture_作用范围_test.py
@IDE     ：PyCharm
@Author  ：XiaoDengYa
@Date    ：2021/6/2/002 14:25
"""

"""
fixture的作用范围
fixture里面有个scope参数可以控制fixture的作用范围：session>module>class>function
-function：每一个函数或方法都会调用
-class：每一个类调用一次，一个类中可以有多个方法
-module：每一个.py文件调用一次，该文件内又有多个function和class
-session：是多个文件调用一次，可以跨.py文件调用，每个.py文件就是module

fixture源码详解
fixture（scope='function'，params=None，autouse=False，ids=None，name=None）：
scope：有四个级别参数"function"（默认），"class"，"module"，"session"
params：一个可选的参数列表，它将导致多个参数调用fixture功能和所有测试使用它。
autouse：如果True，则为所有测试激活fixture func可以看到它。如果为False则显示需要参考来激活fixture
ids：每个字符串id的列表，每个字符串对应于params这样他们就是测试ID的一部分。如果没有提供ID它们将从params自动生成
name：fixture的名称。这默认为装饰函数的名称。如果fixture在定义它的统一模块中使用，夹具的功能名称将被请求夹具的功能arg遮蔽，解决这个问题的一种方法时将装饰函数命令"fixture_<fixturename>"然后使用"@pytest.fixture（name='<fixturename>'）"。
"""


# scope="function" @pytest.fixture() scope的默认参数为 function

import pytest

"""
@pytest.fixture()
def test1():
    a = 'leo'
    print('\n传出a')
    return a


@pytest.fixture(scope='function')
def test2():
    b = '男'
    print('\n传出b')
    return b


def test3(test1):
    name = 'leo'
    print('找到name')
    assert test1 == name


def test4(test2):
    sex = '男'
    print('找到sex')
    assert test2 == sex
    
"""

# 放至类中
"""
@pytest.fixture()
def test1():
    a = 'leo'
    print('\n传出a')
    return a


@pytest.fixture(scope='function')
def test2():
    b = '男'
    print('\n传出b')
    return b


class TestCase:
    def test3(self, test1):
        name = 'leo'
        print('找到name')
        assert test1 == name

    def test4(self, test2):
        sex = '男'
        print('找到sex')
        assert test2 == sex
"""

# scope="class" fixture为class级别的时候，如果一个class里面有多个用例，都调用了次fixture，那么此fixture只在此class里所有用例开始前执行一次。
"""
@pytest.fixture(scope='class')
def test1():
    b = '男'
    print('传出了%s, 且只在class里所有用例开始前执行一次！！！' % b)
    return b


class TestCase:
    def test3(self, test1):
        name = '男'
        print('找到name')
        assert test1 == name

    def test4(self, test1):
        sex = '男'
        print('找到sex')
        assert test1 == sex

"""

# scope="module" fixture为module时，在当前.py脚本里面所有用例开始前只执行一次。
"""
@pytest.fixture(scope='module')
def test1():
    b = '男'
    print('传出了%s, 且在当前py文件下执行一次！！！' % b)
    return b


def test3(test1):
    name = '男'
    print('找到name')
    assert test1 == name


class TestCase:

    def test4(self, test1):
        sex = '男'
        print('找到sex')
        assert test1 == sex
"""
"""
def test3(test1):
    name = '男'
    print('找到name')
    assert test1 == name

"""

# 调用fixture的三种方法
# 1.函数或类里面方法直接传fixture的函数参数名称
"""
@pytest.fixture()
def test1():
    print('\n开始执行function')


def test_a(test1):
    print('---用例a执行---')


class TestCase:

    def test_b(self, test1):
        print('---用例b执行')
"""

# 2.使用装饰器@pytest.mark.usefixtures()修饰需要运行的用例
"""
@pytest.fixture()
def test1():
    print('\n开始执行function')


@pytest.mark.usefixtures('test1')
def test_a():
    print('---用例a执行---')


@pytest.mark.usefixtures('test1')
class TestCase:

    def test_b(self):
        print('---用例b执行---')

    def test_c(self):
        print('---用例c执行---')
"""
# 叠加usefixtures
# 如果一个方法或者一个class用例想要同时调用多个fixture，可以使用@pytest.mark.usefixture()进行叠加。注意叠加顺序，先执行的放底层，后执行的放上层。

"""
@pytest.fixture()
def test1():
    print('\n开始执行function1')


@pytest.fixture()
def test2():
    print('\n开始执行function2')


@pytest.mark.usefixtures('test1')
@pytest.mark.usefixtures('test2')
def test_a():
    print('---用例a执行---')


@pytest.mark.usefixtures('test2')
@pytest.mark.usefixtures('test1')
class TestCase:

    def test_b(self):
        print('---用例b执行---')

    def test_c(self):
        print('---用例c执行---')
"""

"""
usefixtures与传fixture区别
 如果fixture有返回值，那么usefixture就无法获取到返回值，这个是装饰器usefixture与用例直接传fixture参数的区别。
 当fixture需要用到return出来的参数时，只能讲参数名称直接当参数传入，不需要用到return出来的参数时，两种方式都可以。
"""

# fixture自动使用autouse=True
#当用例很多的时候，每次都传这个参数，会很麻烦。fixture里面有个参数autouse，默认是False没开启的，可以设置为True开启自动使用fixture功能，这样用例就不用每次都去传参了

@pytest.fixture(scope='module', autouse=True)
def test1():
    print('\n开始执行module')


@pytest.fixture(scope='class', autouse=True)
def test2():
    print('\n开始执行class')


@pytest.fixture(scope='function', autouse=True)
def test3():
    print('\n开始执行function')


def test_a():
    print('---用例a执行---')


def test_d():
    print('---用例d执行---')


class TestCase:

    def test_b(self):
        print('---用例b执行---')

    def test_c(self):
        print('---用例c执行---')



if __name__ == '__main__':
    pytest.main(["-s", "04_fixture_作用范围_test.py"])